package pers.ree.demo.concurrent;

public class BeforeHappenDemo {

    public boolean found = false;

    // 静态变量或者成员变量都需要加volatile才能执行到"笔来了，开始写字。。。"
//    public volatile boolean found = false;
//    public volatile static boolean found = false;


    public static void main(String[] args) {
        // before happen的顺序规则
//        beforeHappen4OrderDemo();

        // 验证start()的before happen规则
//        beforeHappen4StartDemo();

        /****** 验证join的before happen规则 begin ***/
        final BeforeHappenDemo demo = new BeforeHappenDemo();

        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("begin基友线程demo.found=" + demo.found);
                demo.found = true;
                System.out.println("end基友线程demo.found=" + demo.found);
            }
        }, "基友线程");

        System.out.println("main begin, demo.found=" + demo.found);
        t.start();
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("main end, demo.found=" + demo.found);
        /****** 验证join的before happen规则 end ***/
    }

    public static void demo1() {
        final BeforeHappenDemo demo = new BeforeHappenDemo();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("等基友送笔来。。。");

                long startTimeMillis = System.currentTimeMillis();
                long time = 0;

                // 等待
                while (!demo.found) {
                    time = System.currentTimeMillis() - startTimeMillis;
                    if (time > 5000) {
                        // 同一个线程用的是同一个虚拟机栈，所以demo.found的修改不加volatile也可见
                        demo.found = true;
                        System.out.println("time: " + time + "，等不到基友自己买笔了。。。");
                    }
                }

                System.out.println("笔来了，开始写字。。。");
            }
        }, "我线程").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("基友找到笔了，送过去。。。");
                // 如果found不加volatile，则本线程的修改对"我线程"不可见
                demo.found = true;
            }
        }, "基友线程").start();
    }
}
